#include "mainwindow.h"
#include "constants.h"
#include "boarditem.h"
#include "board.h"
#include "parsercontainer.h"
#include "dialogs/chatwindow.h"

#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QtCore>
#include <QAction>
#include <QApplication>
#include <QMenuBar>
#include <QScrollBar>

MainWindow::MainWindow (QWidget* parent): QMainWindow( parent ) {
  commandEdit = new QLineEdit(this);

  sendCommandButton = new QPushButton( QString(">>"), this );

  consoleOutput = new QTextEdit( this );
  consoleOutput->setReadOnly(true);
  consoleOutput->setLineWrapMode( QTextEdit::WidgetWidth );

  board = new Board;
  boardView = new BoardView( this );
  boardView->hide();

  conn = new Connection(this);
  
  connect( conn, SIGNAL(lineReaded(QString)), this, SLOT(printConsole(QString)) );
  connect( conn, SIGNAL(lineReaded(QString)), this, SLOT(processLine(QString)) );

  ParserContainer* parsers = ParserContainer::getInstance();
  connect( parsers->getParserChat(), SIGNAL(chatPhrase(QString, QString)), this, SLOT(updateChat(QString, QString)) );

  connect( sendCommandButton, SIGNAL(clicked()), this, SLOT(sendCommand()) );
  connect( commandEdit, SIGNAL(returnPressed()), this, SLOT(sendCommand()) );

  setMainLayout();
  setupMenu();
  drawBoard();
}

void MainWindow::setupMenu()
{
  QAction* a;
  a = new QAction(tr("&Quit"), this);
  connect( a, SIGNAL(triggered()), qApp, SLOT(quit()) );
  menuBar()->addAction(a);

  //
  // Setup Connection Menu
  //
  QMenu* connectionMenu = new QMenu(tr("&Connection"), this);
  menuBar()->addMenu(connectionMenu);

  a = new QAction(tr("Co&nnect"), this);
  connect( a, SIGNAL(triggered()), this, SLOT(connectToServer()) );
  connectionMenu->addAction(a);
 
  //
  // Setup View Menu
  //
  QMenu* viewMenu = new QMenu(tr("&View"), this);
  menuBar()->addMenu(viewMenu);

  a = new QAction(tr("&Board"), this);
  a->setCheckable( true );
  connect( a, SIGNAL(triggered(bool)), this, SLOT(changeBoardVisibility(bool)) );
  viewMenu->addAction(a);

  a = new QAction(tr("&Console"), this);
  a->setCheckable( true );
  connect( a, SIGNAL(triggered(bool)), this, SLOT(changeConsoleVisibility(bool)) );
  viewMenu->addAction(a);
  a->trigger();
}

void MainWindow::changeBoardVisibility( bool checked )
{
  qDebug() << "Changing board visibility, checked:" << checked;
  if ( checked ) {
    boardView->show();
  }
  else {
    boardView->hide();
  }
}

void MainWindow::changeConsoleVisibility( bool checked )
{
  qDebug() << "Changing console visibility, checked:" << checked;
  if ( checked ) {
    consoleOutput->show();
    commandEdit->show();
    sendCommandButton->show();
  }
  else {
    consoleOutput->hide();
    commandEdit->hide();
    sendCommandButton->hide();
  }
}

void MainWindow::connectToServer()
{
  conn->connectToServer("dykerguesta\n", "", "freechess.org", 5000);
}

void MainWindow::setMainLayout()
{
  QWidget* centralWidget = new QWidget;
  QHBoxLayout* commandLayout = new QHBoxLayout;
  QVBoxLayout* mainLayout = new QVBoxLayout;

  mainLayout->addWidget( boardView );
  mainLayout->addWidget( consoleOutput );

  commandLayout->addWidget( commandEdit );
  commandLayout->addWidget( sendCommandButton );

  mainLayout->addLayout( commandLayout );

  // hiding everything except board
  commandEdit->hide();
  sendCommandButton->hide();
  consoleOutput->hide();

  setCentralWidget( centralWidget );
  centralWidget->setLayout( mainLayout );
}

void MainWindow::printConsole(const QString& str)
{
  qDebug() << "Data from connection come";
  consoleOutput->moveCursor( QTextCursor::End );
  consoleOutput->insertPlainText( str );
  consoleOutput->moveCursor( QTextCursor::End );
  consoleOutput->insertPlainText( "\n" );
  QScrollBar* scrollBar = consoleOutput->verticalScrollBar();
  scrollBar->setValue( scrollBar->maximum() );
}

void MainWindow::processLine(const QString& str)
{
  qDebug() << "Data from connection parsing";
  ParserContainer* parsers = ParserContainer::getInstance();
  parsers->processLine( str );
}

void MainWindow::updateChat( const QString& login, const QString& phrase )
{
  qDebug() << login << " TOLD YOU: " << phrase;
  ChatWindow* wnd;
  if (chatWindows.contains(login)) {
    wnd = chatWindows[login];
    wnd->addPhrase( QString("> %1").arg(phrase) );
  }
  else {
    wnd = new ChatWindow( login, phrase, this );
    chatWindows[login] = wnd;
    connect( wnd, SIGNAL(sendCommand(QString)), this, SLOT(sendExternalCommand(QString)));
  }
  wnd->raise();
  wnd->showMaximized();
}

void MainWindow::sendExternalCommand(const QString& command)
{
  qDebug() << "~~Sending external command[" << command << "]";
  conn->sendCommand( command );
}

void MainWindow::sendCommand()
{
  qDebug() << "Sending command";
  QString command( commandEdit->text() );
  commandEdit->clear();
  commandEdit->setFocus();
  conn->sendCommand( command );
}

void MainWindow::drawBoard() {
  boardView->setScene( board );
}
